/*
 *  Copyright 2003 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 */

/*
 *  ======== evmdm642_flash_erase.c ========
 *  EVMDM642_FLASH_erase() implementation
 */
 
#include <std.h>
#include <csl.h>

#include <evmdm642.h>
#include <evmdm642_flash.h>

/* Constant table containing end address of each sector */
static Uint32 sector_end[EVMDM642_FLASH_SECTORS] = {
    EVMDM642_FLASH_BASE + 0x00ffff, /* Sector  0 */
    EVMDM642_FLASH_BASE + 0x01ffff, /* Sector  1 */
    EVMDM642_FLASH_BASE + 0x02ffff, /* Sector  2 */
    EVMDM642_FLASH_BASE + 0x03ffff, /* Sector  3 */
    EVMDM642_FLASH_BASE + 0x04ffff, /* Sector  4 */
    EVMDM642_FLASH_BASE + 0x05ffff, /* Sector  5 */
    EVMDM642_FLASH_BASE + 0x06ffff, /* Sector  6 */
    EVMDM642_FLASH_BASE + 0x07ffff  /* Sector  7 */
};


/* Erase a segment of Flash memory */
void EVMDM642_FLASH_erase(Uint32 start, Uint32 length)
{
    Int16 i;
    Uint8 *pdata;
    Uint32 sector_base, end;
    
    /* Calculate extents of range to erase */
    end = start + length - 1;
    
    /* Walk through each sector, erase any sectors within range */
    sector_base = EVMDM642_FLASH_BASE;
    for (i = 0; i < EVMDM642_FLASH_SECTORS; i++)
    {
        if ((start <= sector_base) && (sector_end[i] <= end))
        {
            /* Start sector erase sequence */
            *((Uint8 *)EVMDM642_FLASH_BASE) = 0xaa;
            *((Uint8 *)EVMDM642_FLASH_BASE) = 0x55;
            *((Uint8 *)EVMDM642_FLASH_BASE) = 0x80;
            *((Uint8 *)EVMDM642_FLASH_BASE) = 0xaa;
            *((Uint8 *)EVMDM642_FLASH_BASE) = 0x55;
            
            /* Start erase at sector address */
            pdata = (Uint8 *)sector_base;
            *pdata = 0x30;
            
            /* Wait for erase to complete */
            while (1)
                if (*pdata & 0x80)
                    break;
                    
            /* Put back in read mode */
            *((Uint8 *)EVMDM642_FLASH_BASE) = 0xf0;                    
        }
        
        /* Advance to next sector */
        sector_base = sector_end[i] + 1;
    }
}
